#-------------------------------------------------------------------------------
# Name:        module1
# Purpose:
#
# Author:      ingenieria
#
# Created:     19/08/2011
# Copyright:   (c) ingenieria 2011
# Licence:     <your licence>
#-------------------------------------------------------------------------------
#!/usr/bin/env python

import ply.lex as lex

# List of token names.   This is always required

reserved = { 	'abort':'ABORT',
    'access':'ACCESS',
	'action':'ACTION',
	'add':'ADD',
	'admin':'ADMIN',
	'after':'AFTER',
	'aggregate':'AGGREGATE',
	'alignment':'ALIGNMENT',
	'all':'ALL',
	'alter':'ALTER',
	'always':'ALWAYS',
	'analyze':'ANALYZE',
	'and':'AND',
	'any':'ANY',
	'array':'ARRAY',
	'as':'AS',
	'asc':'ASC',
	'authorization':'AUTHORIZATION',
	'before':'BEFORE',
	'begin':'BEGIN',
	'between':'BETWEEN',
	'bigint':'BIGINT',
	'bigserial':'BIGSERIAL',
	'bit':'BIT',
	'bool':'BOOL',
	'boolean':'BOOLEAN',
	'box':'BOX',
	'btree':'BTREE',
	'by':'BY',
	'bytea':'BYTEA',
	'cache':'CACHE',
	'call':'CALL',
	'called':'CALLED',
	'cascade':'CASCADE',
	'case':'CASE',
	'cast':'CAST',
	'category':'CATEGORY',
	'char':'CHAR',
	'character':'CHARACTER',
	'check':'CHECK',
	'checkpoint':'CHECKPOINT',
	'cidr':'CIDR',
	'circle':'CIRCLE',
	'cluster':'CLUSTER',
	'coalesce':'COALESCE',
	'collate':'COLLATE',
	'column':'COLUMN',
	'comment':'COMMENT',
	'commit':'COMMIT',
	'committed':'COMMITTED',
	'comparison':'COMPARISON',
	'concurrently':'CONCURRENTLY',
	'connect':'CONNECT',
	'connection':'CONNECTION',
	'constraint':'CONSTRAINT',
	'constraints':'CONSTRAINTS',
	'continue':'CONTINUE',
	'conversion':'CONVERSION',
	'convert':'CONVERT',
	'cost':'COST',
	'create':'CREATE',
	'createdb':'CREATEDB',
	'createrole':'CREATEROLE',
	'createuser':'CREATEUSER',
	'cross':'CROSS',
	'current':'CURRENT',
	'current_date':'CURRENT_DATE',
	'current_time':'CURRENT_TIME',
	'current_timestamp':'CURRENT_TIMESTAMP',
	'cycle':'CYCLE',
	'data':'DATA',
	'database':'DATABASE',
	'date':'DATE',
	'decimal':'DECIMAL',
	'default':'DEFAULT',
	'defaults':'DEFAULTS',
	'deferrable':'DEFERRABLE',
	'deferred':'DEFERRED',
	'definer':'DEFINER',
	'delete':'DELETE',
	'delimiter':'DELIMITER',
	'desc':'DESC',
	'disable':'DISABLE',
	'discard':'DISCARD',
	'distinct':'DISTINCT',
	'domain':'DOMAIN',
	'double':'DOUBLE',
	'drop':'DROP',
	'each':'EACH',
	'element':'ELEMENT',
	'else':'ELSE',
	'enable':'ENABLE',
	'encoding':'ENCODING',
	'encrypted':'ENCRYPTED',
	'end':'END',
	'enum':'ENUM',
	'equals':'EQUALS',
	'except':'EXCEPT',
	'excluding':'EXCLUDING',
    'exclusive':'EXCLUSIVE',
	'execute':'EXECUTE',
	'exist':'EXIST',
	'exists':'EXISTS',
	'explain':'EXPLAIN',
	'extended':'EXTENDED',
	'external':'EXTERNAL',
	'extract':'EXTRACT',
	'false':'FALSE',
	'fetch':'FETCH',
	'first':'FIRST',
	'float4':'FLOAT4',
	'float8':'FLOAT8',
	'for':'FOR',
	'force':'FORCE',
	'foreing':'FOREING',
	'freeze':'FREEZE',
	'from':'FROM',
	'full':'FULL',
	'function':'FUNCTION',
	'gin':'GIN',
	'gist':'GIST',
	'global':'GLOBAL',
	'grant':'GRANT',
	'group':'GROUP',
	'hash':'HASH',
	'having':'HAVING',
	'identity':'IDENTITY',
	'if':'IF',
	'immediate':'IMMEDIATE',
	'immutable':'IMMUTABLE',
	'in':'IN',
	'including':'INCLUDING',
	'increment':'INCREMENT',
	'index':'INDEX',
	'indexes':'INDEXES',
	'inet':'INET',
	'inherit':'INHERIT',
	'inherits':'INHERITS',
	'initially':'INITIALLY',
	'inner':'INNER',
	'inout':'INOUT',
	'input':'INPUT',
	'insert':'INSERT',
	'int':'INT',
	'int2':'INT2',
	'int4':'INT4',
	'int8':'INT8',
	'integer':'INTEGER',
	'internallength':'INTERNALLENGTH',
	'intersect':'INTERSECT',
	'into':'INTO',
	'invoker':'INVOKER',
	'is':'IS',
	'isnull':'ISNULL',
	'isolation':'ISOLATION',
	'join':'JOIN',
	'key':'KEY',
	'language':'LANGUAGE',
	'last':'LAST',
	'lc_collate':'LC_COLLATE',
	'lc_ctype':'LC_CTYPE',
	'left':'LEFT',
	'level':'LEVEL',
	'like':'LIKE',
	'limit':'LIMIT',
	'line':'LINE',
	'local':'LOCAL',
	'lock':'LOCK',
	'login':'LOGIN',
	'lseg':'LSEG',
	'macaddr':'MACADDR',
	'main':'MAIN',
	'match':'MATCH',
	'maxvalue':'MAXVALUE',
	'minvalue':'MINVALUE',
	'mode':'MODE',
	'money':'MONEY',
	'natural':'NATURAL',
	'new':'NEW',
	'next':'NEXT',
	'no':'NO',
	'nocreatedb':'NOCREATEDB',
	'nocreaterole':'NOCREATEROLE',
	'nocreateuser':'NOCREATEUSER',
	'noinherit':'NOINHERIT',
	'nologin':'NOLOGIN',
	'none':'NONE',
	'nosuperuser':'NOSUPERUSER',
	'not':'NOT',
	'notnull':'NOTNULL',
	'nowait':'NOWAIT',
	'null':'NULL',
	'nullif':'NULLIF',
	'nulls':'NULLS',
	'numeric':'NUMERIC',
	'of':'OF',
	'off':'OFF',
	'offset':'OFFSET',
	'oids':'OIDS',
	'on':'ON',
	'only':'ONLY',
	'operator':'OPERATOR',
	'option':'OPTION',
	'or':'OR',
	'order':'ORDER',
	'out':'OUT',
	'outer':'OUTER',
	'output':'OUTPUT',
	'owned':'OWNED',
	'owner':'OWNER',
	'partial':'PARTIAL',
	'passedbyvalue':'PASSEDBYVALUE',
	'password':'PASSWORD',
	'path':'PATH',
	'plain':'PLAIN',
	'plans':'PLANS',
	'point':'POINT',
	'polygon':'POLYGON',
	'precision':'PRECISION',
	'preferred':'PREFERRED',
	'prepared':'PREPARED',
	'preserve':'PRESERVE',
	'primary':'PRIMARY',
	'privileges':'PRIVILEGES',
	'procedure':'PROCEDURE',
	'public':'PUBLIC',
	'read':'READ',
	'real':'REAL',
	'receive':'RECEIVE',
	'references':'REFERENCES',
	'reindex':'REINDEX',
	'release':'RELEASE',
	'rename':'RENAME',
	'repeatable':'REPEATABLE',
	'replace':'REPLACE',
	'replica':'REPLICA',
	'reset':'RESET',
	'restart':'RESTART',
	'restrict':'RESTRICT',
	'returning':'RETURNING',
	'returns':'RETURNS',
	'revoke':'REVOKE',
	'right':'RIGHT',
	'role':'ROLE',
	'rollback':'ROLLBACK',
	'row':'ROW',
	'rows':'ROWS',
	'savepoint':'SAVEPOINT',
	'schema':'SCHEMA',
	'security':'SECURITY',
	'select':'SELECT',
	'send':'SEND',
	'sequence':'SEQUENCE',
	'serial':'SERIAL',
	'serial4':'SERIAL4',
	'serial8':'SERIAL8',
	'serializable':'SERIALIZABLE',
	'session':'SESSION',
	'set':'SET',
	'share':'SHARE',
	'simple':'SIMPLE',
	'smallint':'SMALLINT',
	'some':'SOME',
	'stable':'STABLE',
	'start':'START',
	'statement':'STATEMENT',
	'statistics':'STATISTICS',
	'storage':'STORAGE',
	'strict':'STRICT',
	'superuser':'SUPERUSER',
	'system':'SYSTEM',
	'table':'TABLE',
	'temp':'TEMP',
	'template':'TEMPLATE',
	'temporary':'TEMPORARY',
	'text':'TEXT',
	'then':'THEN',
	'time':'TIME',
	'timestamp':'TIMESTAMP',
	'timestamptz':'TIMESTAMPTZ',
	'timetz':'TIMETZ',
	'to':'TO',
	'transaction':'TRANSACTION',
	'trigger':'TRIGGER',
	'true':'TRUE',
	'truncate':'TRUNCATE',
	'tsquery':'TSQUERY',
	'tsvector':'TSVECTOR',
	'txid_snapshot':'TXID_SNAPSHOT',
	'type':'TYPE',
	'typmod_in':'TYPMOD_IN',
	'typmod_put':'TYPMOD_PUT',
	'uncommitted':'UNCOMMITTED',
	'unencrypted':'UNENCRYPTED',
	'union':'UNION',
	'unique':'UNIQUE',
	'until':'UNTIL',
	'update':'UPDATE',
	'usage':'USAGE',
	'user':'USER',
	'using':'USING',
	'uuid':'UUID',
	'vacuum':'VACUUM',
	'valid':'VALID',
	'values':'VALUES',
	'varbit':'VARBIT',
	'varchar':'VARCHAR',
	'variable':'VARIABLE',
	'variadic':'VARIADIC',
	'varying':'VARYING',
	'verbose':'VERBOSE',
	'view':'VIEW',
	'volatile':'VOLATILE',
	'when':'WHEN',
	'where':'WHERE',
	'window':'WINDOW',
	'with':'WITH',
	'without':'WITHOUT',
	'work':'WORK',
	'write':'WRITE',
	'xml':'XML',
	'yes':'YES',
	'zone':'ZONE',

}

tokens = [
   'IDENTIFICADOR',
   'NUMERO_ENTERO',
   'NUMERO_DECIMAL',
   'CADENA',
   'BARRA'

] + list(reserved.values())

def t_BARRA(t):
    r'\|\|'
    return t

def t_ESPACIO(t):
    r'\ +'
    pass

def t_COMENTARIO_SIMPLE(t):
    r'--.*'
    pass
    # No return value. Token discarded
    # Con pass el token se descarta

def t_COMENTARIO_MULTILINEA(t):
    r'/\*.*\*/'
    pass


def t_newline(t):
    r'\n+'
    t.lexer.lineno += len(t.value)

def t_IDENTIFICADOR(t):
    r'"?[a-zA-Z_][a-zA-Z_0-9$]*"?'
    if reserved.get(t.value.lower()): # Check for reserved words
        t.type = reserved.get(t.value.lower(),'ID')
        t.value = t.value.upper()
    return t

def t_NUMERO_DECIMAL(t):
    r'\d*\.\d+'
    t.value = float(t.value)
    return t

def t_NUMERO_ENTERO(t):
    r'\d+'
    t.value = int(t.value)
    return t

def t_CADENA(t):
    r'\'.*\''
    return t

# Literales
literals = ['(',')','=',',','*','.',';','-','+','/','[',']','$']

t_ignore = '\t'

# Error handling rule
def t_error(t):
    print "Illegal character '%s'" % t.value[0]
    t.lexer.skip(1)

lexer = lex.lex()

### Give the lexer some input
##lexer.input('"a" \'asd \'')
##
### Tokenize
##while True:
##    tok = lexer.token()
##    if not tok: break      # No more input
##    print tok

def main():
    pass

if __name__ == '__main__':
    main()